package com.eascs.spider.ant.common.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
/**
 * HttpClient工具,用于局域网通信
 * @author hzp
 *
 */
public class HttpUtil {
	
	/**
	 * 
	 * 初始化httpClient
	 * 
	 * @param cookieStore	null则为默认
	 * @return CloseableHttpClient
	 */
	public static CloseableHttpClient initHttpClient(){
        SSLConnectionSocketFactory sslsf = null;
        //PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT)
        		//设置请求和传输超时时间
        		.setConnectTimeout(60000).setConnectionRequestTimeout(30000).setSocketTimeout(60000)
        		.build();
        try {
			SSLContext sslContext = new SSLContextBuilder()
                                .loadTrustMaterial(null, new TrustStrategy() {
                //信任所有证书
                public boolean isTrusted(X509Certificate[] chain,
                                String authType) throws CertificateException {
                    return true;
                }
                    }).build();
			//跳过证书Hostname验证
            sslsf = new SSLConnectionSocketFactory(sslContext,new String[]{"TLSv1"}, null,NoopHostnameVerifier.INSTANCE);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        
		Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslsf)
                .build();
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);
        
        
		HttpClientBuilder httpClientBuilder = HttpClients.custom()
				.setDefaultRequestConfig(globalConfig)
		        .setConnectionManager(poolingHttpClientConnectionManager)
		        .setSSLSocketFactory(sslsf);
		
		//生成httpClient
		CloseableHttpClient client = httpClientBuilder.build();
		
		return client;
	}
	
	/**
	 * post重连
	 * @param client
	 * @param httpPost
     * @return
     */
	public static CloseableHttpResponse execute(CloseableHttpClient client, HttpPost httpPost) {
		
		CloseableHttpResponse response = null;
		int i = 5;
		while (i>0) {
			try {
				response = client.execute(httpPost);
				i = 0;
			} catch (IOException e) {
				i--;
			}
		}
		return response;
	}
	/**
	 * get重连
	 * @param client
	 * @param httpGet
	 * @return
	 */
	public static CloseableHttpResponse execute(CloseableHttpClient client, HttpGet httpGet) {
		CloseableHttpResponse response = null;
		int i = 5;
		while (i>0) {
			try {
				response = client.execute(httpGet);
				i = 0;
			} catch (IOException e) {
				i--;
			}
		}
		return response;
	}
	
	
	/**
	 * 
	 * 初始化get请求
	 * 
	 * @param url 请求链接
	 * @param params 请求参数，默认为null
	 * @return HttpGet
	 */
	public static HttpGet initHttpGet(String url, Map<String,String> params) {
		
		//封装请求参数
    	if(params!=null && !params.isEmpty()){
    		url = url + "?";
    		for(String key:params.keySet()){
    			url = url + key + "=" + params.get(key) + "&";
    		}
    		url = url.substring(0, url.length()-1);
    	}
		HttpGet httpGet = new HttpGet(url);
		return httpGet;
	}
	/**
	 * 
	 * 初始化post请求
	 * 
	 * @param url 请求链接
	 * @param params  请求参数，默认为null
	 * @param charset 请求参数编码方式，默认为UTF-8
	 * @return HttpPost
	 */
	public static HttpPost initHttpPost(String url, Map<String,String> params) {
		HttpPost httpPost = new HttpPost(url);
		
		//封装请求参数
		if(params!=null && !params.isEmpty()){
			try {
				httpPost.setEntity(new UrlEncodedFormEntity(packagePostParams(params),"utf-8"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}	
		}
		
		return httpPost;
	}
	
	/**
	 * 
	 *  初始化post请求
	 * 
	 * @param url 请求链接
	 * @param entity jquery数据
	 * @return
	 */
	public static HttpPost initHttpPost(String url, HttpEntity entity) {
    	HttpPost httpPost = new HttpPost(url);
    	//设置提交参数
		httpPost.setEntity(entity);
		return httpPost;
	}
	/**
	 * 封装post参数
	 * @param postParams
	 * @return
	 */
	public static List<NameValuePair> packagePostParams(Map<String,String> postParams){
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		if(postParams!=null){
			for(String key:postParams.keySet()){
				nvps.add(new BasicNameValuePair(key, postParams.get(key)));
			}
		}
		return nvps;
	}
	
	public static <T> void executePost(CloseableHttpClient client , String url , T t){
		try {
			Map<String, String> params = ObjectUtil.objectToMap(t);
			HttpPost post = initHttpPost(url, params);
			CloseableHttpResponse response = client.execute(post);
			EntityUtils.consumeQuietly(response.getEntity());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
